package com.supermap.dialogs;

import com.supermap.Helper;
import com.supermap.MainFrame;
import com.supermap.data.Enum;
import com.supermap.data.*;
import com.supermap.dialogs.advance.CJDialog;
import com.supermap.mapping.LayerSettingVector;
import com.supermap.ui.MapControl;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ProjTransformDialog extends CJDialog {
    private JComboBox<String> sourceDatasourceComboBox;
    private JComboBox<String> sourceDatasetComboBox;
    private JTextArea sourceCoordinateTextArea;
    private JComboBox<String> targetDatasourceComboBox;
    private JTextField targetDatasetNameTextField;
    private JTextArea targetCoordinateTextArea;
    private JComboBox<CoordSysTransMethod> transformMethodJComboBox;

    private MainFrame mainFrame;
    private Workspace workspace;
    private Datasource sourceDatasource;
    private Dataset sourceDataset;
    private Datasource targetDatasource;
    private PrjCoordSys targetPrjCoordSys;

    public ProjTransformDialog(Frame owner, String title, boolean modal, Workspace workspace, MainFrame mainFrame) {
        super(owner, title, modal, 600, 400, new Object[]{workspace, mainFrame});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        this.workspace = (Workspace) args[0];
        this.mainFrame = (MainFrame) args[1];
    }

    @Override
    protected void initializeCore() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        super.confirmBtn.setText("转换");

        JSplitPane centerPanel = new JSplitPane();
        centerPanel.setDividerLocation(getWidth() / 2 - 10);

        // 源
        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new BorderLayout());

        JPanel sourceDataPanel = new JPanel();
        sourceDataPanel.setBorder(BorderFactory.createTitledBorder("源数据"));
        sourceDataPanel.setLayout(new GridBagLayout());

        JLabel sourceDatasourceLabel = new JLabel("数据源: ");
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        sourceDataPanel.add(sourceDatasourceLabel, gbc);

        sourceDatasourceComboBox = new JComboBox<>();
        Datasources datasources = workspace.getDatasources();
        if (datasources.getCount() > 0) {
            for (int i = 0; i < datasources.getCount(); i++) {
                sourceDatasourceComboBox.addItem(datasources.get(i).getAlias());
            }
            sourceDatasourceComboBox.setSelectedIndex(0);
            sourceDatasource = datasources.get((String) sourceDatasourceComboBox.getSelectedItem());
        }
        sourceDatasourceComboBox.addItemListener(e -> {
            String selectedDatasourceName = (String) e.getItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadSourceDatasetComboBox(sourceDatasetComboBox, datasource);
            sourceDataset = datasource.getDatasets().get((String) sourceDatasetComboBox.getSelectedItem());
        });
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        sourceDataPanel.add(sourceDatasourceComboBox, gbc);

        JLabel sourceDatasetLabel = new JLabel("数据集: ");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        sourceDataPanel.add(sourceDatasetLabel, gbc);

        sourceDatasetComboBox = new JComboBox<>();
        if (sourceDatasourceComboBox.getItemCount() > 0) {
            String selectedDatasourceName = (String) sourceDatasourceComboBox.getSelectedItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadSourceDatasetComboBox(sourceDatasetComboBox, datasource);
            sourceDataset = datasource.getDatasets().get((String) sourceDatasetComboBox.getSelectedItem());
        }
        sourceDatasetComboBox.addItemListener(e -> {
            String selectedDatasetName = (String) e.getItem();
            sourceDataset = sourceDatasource.getDatasets().get(selectedDatasetName);
            PrjCoordSys prjCoordSys = sourceDataset.getPrjCoordSys();
            String text = buildPrjCoordSysText(prjCoordSys);
            sourceCoordinateTextArea.setText(text);
            targetDatasetNameTextField.setText(selectedDatasetName + "_1");
        });
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        sourceDataPanel.add(sourceDatasetComboBox, gbc);

        leftPanel.add(sourceDataPanel, BorderLayout.NORTH);

        JPanel sourceCoordinateSystemPanel = new JPanel();
        sourceCoordinateSystemPanel.setLayout(new BorderLayout());
        sourceCoordinateSystemPanel.setBorder(BorderFactory.createTitledBorder("源坐标系"));

        sourceCoordinateTextArea = new JTextArea();
        sourceCoordinateTextArea.setEditable(false);
        sourceCoordinateTextArea.setLineWrap(true);
        if (sourceDataset != null) {
            PrjCoordSys prjCoordSys = sourceDataset.getPrjCoordSys();
            String text = buildPrjCoordSysText(prjCoordSys);
            sourceCoordinateTextArea.setText(text);
        }
        sourceCoordinateSystemPanel.add(sourceCoordinateTextArea, BorderLayout.CENTER);

        leftPanel.add(sourceCoordinateSystemPanel, BorderLayout.CENTER);

        JPanel projectionPanel = new JPanel();
        projectionPanel.setBorder(BorderFactory.createTitledBorder("参照系转换设置"));
        projectionPanel.setLayout(new GridBagLayout());

        JLabel transformMethodLabel = new JLabel("转换方法: ");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        projectionPanel.add(transformMethodLabel, gbc);

        transformMethodJComboBox = new JComboBox<>();
        Enum[] coordSysTransMethods = CoordSysTransMethod.getEnums(CoordSysTransMethod.class);
        for (Enum coordSysTransMethod : coordSysTransMethods) {
            transformMethodJComboBox.addItem((CoordSysTransMethod) coordSysTransMethod);
        }
        transformMethodJComboBox.setSelectedItem(CoordSysTransMethod.MTH_Prj4);
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        projectionPanel.add(transformMethodJComboBox, gbc);

        JLabel transformParametersLabel = new JLabel("投影转换参数: ");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        projectionPanel.add(transformParametersLabel, gbc);

        JButton transformParametersButton = new JButton("设置");
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        projectionPanel.add(transformParametersButton, gbc);

        leftPanel.add(projectionPanel, BorderLayout.SOUTH);

        centerPanel.setLeftComponent(leftPanel);

        JPanel rightPanel = new JPanel();
        rightPanel.setLayout(new BorderLayout());

        // 目标
        JPanel targetDataPanel = new JPanel();
        targetDataPanel.setLayout(new GridBagLayout());
        targetDataPanel.setBorder(BorderFactory.createTitledBorder("结果另存为"));

        JLabel targetDatasourceLabel = new JLabel("数据源: ");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        targetDataPanel.add(targetDatasourceLabel, gbc);

        targetDatasourceComboBox = new JComboBox<>();
        if (datasources.getCount() > 0) {
            for (int i = 0; i < datasources.getCount(); i++) {
                targetDatasourceComboBox.addItem(datasources.get(i).getAlias());
            }
            targetDatasourceComboBox.setSelectedIndex(0);
            targetDatasource = datasources.get((String) targetDatasourceComboBox.getSelectedItem());
        }
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        targetDataPanel.add(targetDatasourceComboBox, gbc);

        JLabel targetDatasetLabel = new JLabel("数据集: ");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        targetDataPanel.add(targetDatasetLabel, gbc);

        targetDatasetNameTextField = new JTextField();
        Object selectedItem = sourceDatasetComboBox.getSelectedItem();
        if (selectedItem != null) {
            targetDatasetNameTextField.setText(selectedItem + "_1");
        }
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 10;
        gbc.fill = GridBagConstraints.BOTH;
        targetDataPanel.add(targetDatasetNameTextField, gbc);

        rightPanel.add(targetDataPanel, BorderLayout.NORTH);

        JPanel targetCoordinateSystemPanel = new JPanel();
        targetCoordinateSystemPanel.setLayout(new BorderLayout());
        targetCoordinateSystemPanel.setBorder(BorderFactory.createTitledBorder("目标坐标系"));

        JMenuBar targetMenuBar = new JMenuBar();
        JMenu targetMenu = new JMenu("目标坐标系");
        JMenuItem targetCoordinateItem1 = new JMenuItem("4326");
        targetCoordinateItem1.addActionListener(e -> {
            targetPrjCoordSys = PrjCoordSys.fromEPSG(4326);
            String targetText = buildPrjCoordSysText(targetPrjCoordSys);
            targetCoordinateTextArea.setText(targetText);
        });
        targetMenu.add(targetCoordinateItem1);
        JMenuItem targetCoordinateItem2 = new JMenuItem("3857");
        targetCoordinateItem2.addActionListener(e -> {
            targetPrjCoordSys = PrjCoordSys.fromEPSG(3857);
            String targetText = buildPrjCoordSysText(targetPrjCoordSys);
            targetCoordinateTextArea.setText(targetText);
        });
        targetMenu.add(targetCoordinateItem2);
        targetMenuBar.add(targetMenu);

        targetCoordinateSystemPanel.add(targetMenuBar, BorderLayout.NORTH);

        targetCoordinateTextArea = new JTextArea();
        targetCoordinateTextArea.setEditable(false);
        targetCoordinateTextArea.setLineWrap(true);
        targetCoordinateSystemPanel.add(targetCoordinateTextArea, BorderLayout.CENTER);

        rightPanel.add(targetCoordinateSystemPanel, BorderLayout.CENTER);

        centerPanel.setRightComponent(rightPanel);

        add(centerPanel, BorderLayout.CENTER);
    }

    @Override
    protected void doConfirmCore() {
        setVisible(false);
        String targetDatasetName = targetDatasetNameTextField.getText();
        Dataset newTargetDataset = targetDatasource.copyDataset(sourceDataset, targetDatasetName, EncodeType.NONE);
        if (CoordSysTranslator.convert(newTargetDataset, targetPrjCoordSys, new CoordSysTransParameter(), (CoordSysTransMethod) transformMethodJComboBox.getSelectedItem())) {
            Helper.showDatasetVectorsComparison("投影转换结果", sourceDataset, newTargetDataset, mainFrame);
        } else {
            JOptionPane.showMessageDialog(getOwner(), "投影转换失败！", "投影转换", JOptionPane.ERROR_MESSAGE);
        }
    }

    private String buildPrjCoordSysText(PrjCoordSys prjCoordSys) {
        StringBuilder pcsStringBuilder = new StringBuilder();
        GeoCoordSys geoCoordSys = prjCoordSys.getGeoCoordSys();
        if (geoCoordSys == null) {
            return pcsStringBuilder.toString();
        }

        GeoDatum geoDatum = geoCoordSys.getGeoDatum();
        GeoSpheroid geoSpheroid = geoDatum.getGeoSpheroid();
        pcsStringBuilder.append("坐标系名称    ").append(prjCoordSys.getName()).append("\n");
        pcsStringBuilder.append("坐标系单位    ").append(prjCoordSys.getCoordUnit().toString()).append("\n");
        int epsgCode = prjCoordSys.getEPSGCode();
        pcsStringBuilder.append("EPSG Code   ").append(epsgCode == 0 ? "无" : epsgCode).append("\n");
        pcsStringBuilder.append("大地基准面    ").append(geoDatum.getName()).append("\n");
        pcsStringBuilder.append("参考椭球体    ").append(geoSpheroid.getName()).append("\n");
        pcsStringBuilder.append("椭球长半轴    ").append(geoSpheroid.getAxis()).append("\n");
        pcsStringBuilder.append("椭球扁率      ").append(geoSpheroid.getFlatten()).append("\n");
        pcsStringBuilder.append("中央子午线    ").append(geoCoordSys.getGeoPrimeMeridian().getLongitudeValue());
        return pcsStringBuilder.toString();
    }

    private void loadSourceDatasetComboBox(JComboBox<String> sourceDatasetComboBox, Datasource datasource) {
        if (sourceDatasetComboBox == null) {
            return;
        }
        sourceDatasetComboBox.removeAll();
        if (datasource != null) {
            Datasets datasets = datasource.getDatasets();
            if (datasets.getCount() > 0) {
                for (int i = 0; i < datasets.getCount(); i++) {
                    sourceDatasetComboBox.addItem(datasets.get(i).getName());
                }
                sourceDatasetComboBox.setSelectedIndex(0);
            }
        }
    }
}
